package com.site.common.context;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.springframework.util.Assert;

/**
 * 获取配置文件的值，供Java调用。
 * 
 * 这个类使用单例模式，并保证spring与其它调用都是对同一实例进行操作。
 * 不把properties定义成 static 且用spring setter直接注入的原因是：避免静态变量直接使用实例方法写入。
 * 
 * @author 刘圳
 * @date 2010-6-23
 * @version $Revision$
 * @see CommonContextLoader
 */
public final class PropsLoader {

	/*
	 * 单例模式
	 */
	private PropsLoader() {
		//System.out.println("create instance of PropsLoader");
	}

	private Properties properties;

	/* 实际使用的实例，必须要约束外部操作都是使用该实例 */
	private static PropsLoader instance = new PropsLoader();

	// ~~~~~ 内部方法 ~~~~~

	private void checkProperties() {
		if (properties == null) {
			throw new IllegalStateException("properties未注入");
		}
	}

	private void setImpl(Properties properties) {
		Assert.notNull(properties, "properties不能为空");
		this.properties = properties;
	}

	private Properties getImpl() {
		checkProperties();
		return this.properties;
	}

	private String getImpl(String key) {
		checkProperties();
		return properties.getProperty(key);
	}

	private String getImpl(String key, String defaultValue) {
		checkProperties();
		return properties.getProperty(key, defaultValue);
	}

	@SuppressWarnings("unchecked")
	private Map<String, String> getMapImpl(String prefix, boolean removePrefix) {
		checkProperties();

		Map<String, String> result = new HashMap<String, String>();
		Enumeration<String> enu = (Enumeration<String>) properties.propertyNames();

		while (enu.hasMoreElements()) {
			String key = enu.nextElement();
			if (key.startsWith(prefix)) {
				String value = properties.getProperty(key);
				if (removePrefix) {
					key = key.substring(prefix.length());
				}
				result.put(key, value);
			}
		}
		return result;
	}

	// ~~~~~ 公共对外接口 ~~~~~

	public static void setProperties(Properties properties) {
		instance.setImpl(properties);
	}

	public static Properties getProperties() {
		return instance.getImpl();
	}

	public static String get(String key) {
		return instance.getImpl(key);
	}

	public static String get(String key, String defaultValue) {
		return instance.getImpl(key, defaultValue);
	}

	public static Map<String, String> getMap(String prefix, boolean removePrefix) {
		return instance.getMapImpl(prefix, removePrefix);
	}
}
